package com.example.googlemaptest;

import java.text.DecimalFormat;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends Activity implements LocationListener,
		GooglePlayServicesClient.ConnectionCallbacks,
		GooglePlayServicesClient.OnConnectionFailedListener {
	/*
	 * Define a request code to send to Google Play services This code is
	 * returned in Activity.onActivityResult
	 */
	private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

	private static final String TAG = "GoogleMap";

	GoogleMap myMap;
	Location globalLocation;
	TextView locationTextView;

	private LatLng destLatLng = null;

	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		int status = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(getApplicationContext());
		if (status == ConnectionResult.SUCCESS) {
			Log.i(TAG, "Google Play services is available");

			String destLongitude = "9893581"; // x fra rejseplanen
			String destLatitude = "57023539"; // y fra rejseplanen

			// init GoogleMap
			myMap = ((MapFragment) getFragmentManager().findFragmentById(
					R.id.map)).getMap();

			myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

			// set button "find me" in googlemap
			myMap.setMyLocationEnabled(true);

			LocationManager locationManager; // LocationManager (
			String serviceName = Context.LOCATION_SERVICE; // get service
															// context
			locationManager = (LocationManager) getSystemService(serviceName); // Init
																				// LocationManager
																				// with
																				// service
																				// context

			Criteria criteria = new Criteria(); // Init Criteria
			criteria.setAccuracy(Criteria.ACCURACY_FINE); // Set accuracy for
															// criteria
			criteria.setPowerRequirement(Criteria.POWER_LOW); // Set
																// powerrequirements
			criteria.setAltitudeRequired(false); // Altitude not needed
			criteria.setBearingRequired(false); // Bearing not needed
			criteria.setSpeedRequired(false); // Speed not required
			criteria.setCostAllowed(true); // Indicates whether the provider is
											// allowed to incur monetary cost.

			// Set provider with defined criteria using locationManager
			String provider = locationManager.getBestProvider(criteria, true);

			// String provider = LocationManager.GPS_PROVIDER
			Location location = locationManager.getLastKnownLocation(provider);

			// Init TextView
			locationTextView = (TextView) findViewById(R.id.locationTextView);

			// updateWithNewLocation(location);

			LatLng myPos = new LatLng(location.getLatitude(),
					location.getLongitude());

			setDestination(destLatitude, destLongitude);

			LatLng destination = destination();

			myMap.addMarker(new MarkerOptions().anchor(0.0f, 1.0f) // Anchors
																	// the
																	// marker on
																	// the
																	// bottom
																	// left
					.position(destination));

			if (myPos != null) {
				calculateDistance(myPos, destination);
			}

			locationManager.requestLocationUpdates(provider, 500, 1,
					locationListener);

			myMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myPos, 13));

			CameraPosition cameraPosition = CameraPosition.builder()
					.target(myPos).zoom(13).build();

			// Animate the change in camera view over 1 seconds
			myMap.animateCamera(CameraUpdateFactory
					.newCameraPosition(cameraPosition));

			// myMap.animateCamera(
			// CameraUpdateFactory.newCameraPosition(cameraPosition), 1000,
			// null);

			// animateMap(location);
		}

	}

	private final LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			LatLng myPos = new LatLng(Double.valueOf(lat), Double.valueOf(lng));
			calculateDistance(myPos, destination());
		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub

		}
	};

	private void setDestination(String lat, String lng) {
		String latitude = lat;
		String longitude = lng;

		latitude = latitude.substring(0, 2) + "."
				+ latitude.substring(2, latitude.length());
		// Toast.makeText(this, latitude, Toast.LENGTH_LONG).show();
		int longitudeIntSubstring = Integer.valueOf(longitude.substring(0, 1));
		if (longitudeIntSubstring > 2) {
			longitude = longitude.substring(0, 1) + "."
					+ longitude.substring(1, longitude.length());

		} else {
			longitude = longitude.substring(0, 2) + "."
					+ longitude.substring(2, longitude.length());

		}
		destLatLng = new LatLng(Double.valueOf(latitude),
				Double.valueOf(longitude));
	}

	private LatLng destination() {
		return destLatLng;
	}

	public void calculateDistance(LatLng startPos, LatLng endPos) {

		DecimalFormat newFormat = new DecimalFormat("####");

		int radius = 6371; // radius of earth in Km.

		double lat1 = startPos.latitude;
		double lat2 = endPos.latitude;
		double lon1 = startPos.longitude;
		double lon2 = endPos.longitude;

		double dLat = Math.toRadians(lat2 - lat1);
		double dLon = Math.toRadians(lon2 - lon1);

		double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
				+ Math.cos(Math.toRadians(lat1))
				* Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
				* Math.sin(dLon / 2);

		double c = 2 * Math.asin(Math.sqrt(a));

		double valueResult = radius * c;

		int valueResultInDec = Integer.valueOf(newFormat
				.format(valueResult * 1000));

		Log.d(TAG, "************************************");
		Log.i(TAG, "ValueResult: " + valueResult);
		Log.i(TAG, "ValueResultInDec: " + valueResultInDec);

		String distance = valueResultInDec + " meter";

		locationTextView.setText(distance);

		if (valueResultInDec < 300) {
			Toast.makeText(getApplicationContext(),
					"Du ankommer om " + valueResultInDec + " meter",
					Toast.LENGTH_LONG).show();
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void showOrHideMap(View v) {
		View f = (View) findViewById(R.id.map);
		Button b = (Button) findViewById(R.id.showHideButton);
		if (f.getVisibility() == View.GONE) {
			f.setVisibility(View.VISIBLE);
			b.setText("Skjul kortet");
		} else {
			f.setVisibility(View.GONE);
			b.setText("Vis kortet");
		}
	}

	public void animateToDestination(View v) {
		CameraPosition cameraPosition = CameraPosition.builder()
				.target(destination()).zoom(16).build();

		// Animate the change in camera view over 1 seconds
		myMap.animateCamera(CameraUpdateFactory
				.newCameraPosition(cameraPosition));
	}

	@Override
	public void onLocationChanged(Location location) {
		double newLatitude = location.getLatitude();
		double newLongitude = location.getLongitude();
		LatLng newPos = new LatLng(newLatitude, newLongitude);
		calculateDistance(newPos, destination());

		String msg = "Updated Location: "
				+ Double.toString(location.getLatitude()) + ","
				+ Double.toString(location.getLongitude());
		Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onConnectionFailed(ConnectionResult connectionResult) {
		/*
		 * Google Play services can resolve some errors it detects. If the error
		 * has a resolution, try sending an Intent to start a Google Play
		 * services activity that can resolve error
		 */
		if (connectionResult.hasResolution()) {
			try {
				connectionResult.startResolutionForResult(this,
						CONNECTION_FAILURE_RESOLUTION_REQUEST);
				/*
				 * Thrown if Google Play services canceled the original
				 * PendingIntent
				 */
			} catch (IntentSender.SendIntentException e) {
				e.printStackTrace();
			}
		} else {
			/*
			 * If no resolution is available, display a dialog to the user with
			 * the error
			 */

		}
	}

	@Override
	public void onConnected(Bundle arg0) {
		Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onDisconnected() {
		Toast.makeText(this, "Disconnected. Please re-connect",
				Toast.LENGTH_SHORT).show();
	}
}
